<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="tutorial.css">
<TITLE>
If it doesn't Work
</TITLE>
</HEAD>
<BODY >
<A HREF="tutorial007.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="tutorial009.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H1 CLASS="chapter"><A NAME="htoc69">Chapter&nbsp;7</A>&nbsp;&nbsp;If it doesn't Work</H1><UL>
<LI><A HREF="tutorial008.html#toc41">Understanding failure</A>
<LI><A HREF="tutorial008.html#toc42">Checking program points</A>
<LI><A HREF="tutorial008.html#toc43">Debugger</A>
</UL>

<A NAME="ifitdoesntwork"></A>
Suppose we have followed our methodology, and just made some modification of our previously running program. Unfortunately, after the change the program stops working. What do we do next to find the problem and to correct it? We first have to understand what types of errors<A NAME="@default226"></A> can occur in an ECLiPSe program.<BR>
<BR>
<A NAME="toc41"></A>
<H2 CLASS="section"><A NAME="htoc70">7.1</A>&nbsp;&nbsp;Understanding failure</H2>
We can distinguish five types of failure<A NAME="@default227"></A>, each with its own set of causes and possible remedies.<BR>
<BR>

<H3 CLASS="subsection"><A NAME="htoc71">7.1.1</A>&nbsp;&nbsp;Run-time errors</H3> 
Run-time errors<A NAME="@default228"></A><A NAME="@default229"></A> occur if we call a built-in predicate with a wrong argument pattern. This will usually either be a type mismatch<A NAME="@default230"></A>, i.e. using a number where an atom is expected, or an instantiation problem, i.e. passing a variable where a ground value was expected or vice versa. In this case the ECLiPSe system prints out the offending call together with an error message<A NAME="@default231"></A> indicating the problem. If we are lucky, we can identify the problem immediately, otherwise we may have to look up the documentation of the built-in to understand the problem.<BR>
<BR>
In the following example <I>bug0</I>, we have called the predicate <I>open/3</I><A NAME="@default232"></A> with an incorrect first argument.
<PRE>
:-export(bug0/0).
bug0:-
        open(1,read,S), % wrong
        read(S,X),
        writeln(X),
        close(S).
</PRE>
When we run the query <I>bug0</I>, the ECLiPSe system prints out the message:
<A NAME="@default233"></A>
<PRE CLASS="verbatim">
type error in open(1, read, S)
</PRE>In general run-time errors are quite simple to locate and to fix. But the system does not indicate which particular call of a built-in is to blame. We may need to use the tracer to find out which of dozens of calls to the predicate <I>is/2</I> for example may have caused a particular problem. There are several things that may help to avoid the tedious tracing. 
<UL CLASS="itemize"><LI CLASS="li-itemize">
If the call to the predicate contains some variable name, we may be able to locate the problem by searching for that name in the source file(s). 
<LI CLASS="li-itemize">Well placed logging messages may also be helpful, they indicate which program part is responsible.
<LI CLASS="li-itemize">If we have only applied a small change to a previously working program, then it is likely that the error is located close to the change we have made. Testing the program after each change will speed up development.
</UL> 

<H3 CLASS="subsection"><A NAME="htoc72">7.1.2</A>&nbsp;&nbsp;Environment limits</H3> 
<A NAME="@default234"></A>These errors occur when we hit some limit of the run-time system, typically exceeding available memory<A NAME="@default235"></A>. An example is the run-away recursion in the program <I>bug1</I> below:
<PRE>
:-export(bug1/0).
bug1:-
        lp(X),  % wrong
        writeln(X).

lp([_H|T]):-
        lp(T).
lp([]).
</PRE>
After some seconds, the system returns an error message of the form:
<FONT SIZE=2>
</FONT><A NAME="@default236"></A><FONT SIZE=2>
</FONT><PRE CLASS="verbatim"><FONT SIZE=2>
*** Overflow of the local/control stack!
You can use the "-l kBytes" (LOCALSIZE) option to have a larger stack.
Peak sizes were: local stack 13184 kbytes, control stack 117888 kbytes
</FONT></PRE>
Typical error sources are passing free variables to a recursion, where the terminating clause is not executed first or the use of an infinite data structure.<BR>
<BR>

<H3 CLASS="subsection"><A NAME="htoc73">7.1.3</A>&nbsp;&nbsp;Failure</H3> Probably the most common error symptom is a failure<A NAME="@default237"></A> of the application. Instead of producing an answer, the system returns 'no'<A NAME="@default238"></A>. This is caused by: 
<UL CLASS="itemize"><LI CLASS="li-itemize">
Calling a user-defined predicate <A NAME="@default239"></A>with the wrong calling pattern. If none of the rules of a predicate matches the calling pattern, then the predicate will fail. Of course, quite often this is intentional (tests for some condition for example). It becomes a problem if the calling predicate does not handle the failure properly. We should know for each predicate that we define if it can fail and make sure that any calling predicate handles that situation.
<LI CLASS="li-itemize">Calling a built-in predicate with arguments so that it fails unexpectedly. This is much less likely, but some built-in predicates can fail if the wrong arguments are passed.
<LI CLASS="li-itemize">Wrong control structure. A common problem is to miss the alternative branch in an <I>if-then-else construct</I><A NAME="@default240"></A>. If the condition part fails, then the whole call fails. We must always add an <I>else</I> <A NAME="@default241"></A>part, perhaps with an empty statement <I>true</I><A NAME="@default242"></A>.
</UL>
The best way of finding failures is by code inspection, helped by logging messages which indicate the general area of the failure. If this turns out to be too complex, we may have to use the tracer.<BR>
<BR>

<H3 CLASS="subsection"><A NAME="htoc74">7.1.4</A>&nbsp;&nbsp;Wrong answer</H3> 
More rare is the situation where a &#8220;wrong&#8221; answer <A NAME="@default243"></A>is returned. This means that the program computes a result, which we do not accept as an answer. The cause of the problem typically lies in a mismatch of the intended behaviour of the program (what we think it is doing) and the actual behaviour.<BR>
<BR>
In a constraint problem we then have to identify which constraint(s) should eliminate this answer and why that didn't happen. There are two typical scenarios.
<UL CLASS="itemize"><LI CLASS="li-itemize">
The more simple one is caused by missing a constraint alltogether, or misinterpreting the meaning of a constraint that we did include. 
<LI CLASS="li-itemize">The more complex scenario is a situation where the constraint did not trigger and therefore was not activated somewhere in the program execution. 
</UL>
We can often distinguish these problems by re-stating the constraint a second time after the wrong answer has been found. <BR>
<BR>
If the constraint still accepts the solution, then we can assume that it simply does not exclude this solution. We will have to reconsider the declarative definition of the constraint to reject this wrong answer.<BR>
<BR>
If the program fails when the constraint is re-stated, then we have a problem with the dynamic execution of the constraints in the constraint solver. That normally is a much more difficult problem to solve, and may involve the constraint engine itself.<BR>
<BR>

<H3 CLASS="subsection"><A NAME="htoc75">7.1.5</A>&nbsp;&nbsp;Missing answer</H3> Probably the most complex problem is a missing answer<A NAME="@default244"></A>, i.e. the program produces correct answers, but not all of them. This assumes that we know this missing answer, or we know how many answers there should be to a particular problem and we get a different count when we try to generate them all. In the first case we can try to instantiate our problem variables with the missing answer before stating the constraints and then check where this solution is rejected.<BR>
<BR>
This type of problem often occurs when we develop our own constraints and have made a mistake in one of the propagation rules<A NAME="@default245"></A>. It should not occur if we use a pre-defined constraint solver.<BR>
<BR>
<A NAME="toc42"></A>
<H2 CLASS="section"><A NAME="htoc76">7.2</A>&nbsp;&nbsp;Checking program points</H2>
A very simple debugging technique is the logging <A NAME="@default246"></A>of certain predicate calls as they occur in the program.
<PRE CLASS="verbatim">
:-export(bug2/0).

bug2:-
        ...
        generate_term(Term),
        analyze_term(Term,Result),
        ...
</PRE>Suppose we assume that the predicate <I>analyze_term</I> is responsible for a problem. We can then simply add a <I>writeln</I> call before and/or after the predicate call to print out the suspected predicate. The output before that call should show all input arguments, the output after the call should also show the output results.
<PRE CLASS="verbatim">
:-export(bug2/0).

bug2:-
        ...
        generate_term(Term),
        writeln(analyze_term(Term,Result)),
        analyze_term(Term,Result),
        writeln(analyze_term(Term,Result)),
        ...
</PRE>Used sparingly for suspected problems, this technique can avoid the use of the debugger and at the same time give a clear indication of the problem. The ECLiPSe system will normally restrict the output of a term to a certain complexity, so that long lists are not printed completely. This can be influenced by the <I>print_depth</I><A NAME="@default247"></A> flag of <I>set_flag</I><A NAME="@default248"></A>.<BR>
<BR>
Such messages can be written to the <I>log_output</I> stream (or a user-defined stream) which can be later be discarded by
<PRE CLASS="verbatim">
set_stream(log_output,null)
</PRE>or which can be directed to a log file. This can be useful in &#8220;live&#8221; code, in order to capture information about problems in failure cases.
<A NAME="toc43"></A>
<H2 CLASS="section"><A NAME="htoc77">7.3</A>&nbsp;&nbsp;Debugger</H2>
Ideally, we can figure out all problems without running the application in the debugger<A NAME="@default249"></A>. But at some point we may need to understand what the system is doing in more detail. We can then start the ECLiPSe tracer<A NAME="@default250"></A> tool from the <I>Tools</I> menu. Figure <A HREF="#Tracer">7.1</A> shows a typical output. In the top window we see the current stack of predicate calls, in the bottom we see a history of the program execution. 
<BLOCKQUOTE CLASS="figure"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
figure=tracer.eps,width=13.7cm
<BR>
<BR>
<DIV CLASS="center">Figure 7.1: <A NAME="Tracer"></A>ECLiPSe Tracer</DIV><BR>
<BR>

<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>

<H3 CLASS="subsection"><A NAME="htoc78">7.3.1</A>&nbsp;&nbsp;Tracing</H3>
The three buttons <I>Creep</I><A NAME="@default251"></A>, <I>Skip</I><A NAME="@default252"></A>, <I>Leap</I><A NAME="@default253"></A> show the main commands of the tracer. The creep operation single-steps to the next statement in the program. The skip operation executes the current query and stops again when that query either succeeds or fails. The leap operation continues execution until it reaches a spy point<A NAME="@default254"></A>, a predicate call for which we have indicated some interest before.<BR>
<BR>
A normal debugging session consists of a sequence of leap, skip and creep operations to reach an interesting part of the program and then a more detailed step-by step analysis of what is happening. It is pointless and very time consuming to single-step through a part of the program that we have already checked, but we have to be careful not to skip over the interesting part of the program.<BR>
<BR>

<H3 CLASS="subsection"><A NAME="htoc79">7.3.2</A>&nbsp;&nbsp;Jumping to a program point</H3>
In a large program, it may be difficult to leap directly to the interesting part of the program. But we may have to repeat this operation several times, if we repeatedly leap/skip over an interesting statement. We can use the invocation number of a statement to jump<A NAME="@default255"></A> to this exact place in the execution again. The invocation number<A NAME="@default256"></A> is printed in parentheses at the beginning of each trace line. By re-starting the debugger, copying this number into the text field to the right of the button <I>To Invoc:</I><A NAME="@default257"></A> and then pressing this button we can directly jump to this location.<BR>
<BR>
Unfortunately, jumping to an invocation number can be quite slow in a large program. The debugger has to scan each statement to check its invocation number. It can be faster (but more tedious) to use skip and leap commands to reach a program point<SUP><A NAME="text9" HREF="#note9">1</A></SUP>.<BR>
<BR>
<HR WIDTH="50%" SIZE=1><DL CLASS="list"><DT CLASS="dt-list"><A NAME="note9" HREF="#text9"><FONT SIZE=5>1</FONT></A><DD CLASS="dd-list">Experiment! Your mileage may vary!
</DL>
<HR>
<A HREF="tutorial007.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="tutorial009.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
